package com.jia.leetCode;
/**
 * 840.矩阵中的幻方
 * 3 x 3 的幻方是一个填充有从 1 到 9 的不同数字的 3 x 3 矩阵，其中每行，每列以及两条对角线上的各数之和都相等。

给定一个由整数组成的 grid，其中有多少个 3 × 3 的 “幻方” 子矩阵？（每个子矩阵都是连续的）。

 

示例：

输入: [[4,3,8,4],
      [9,5,1,9],
      [2,7,6,2]]
输出: 1
解释: 
下面的子矩阵是一个 3 x 3 的幻方：
438
951
276

而这一个不是：
384
519
762

总的来说，在本示例所给定的矩阵中只有一个 3 x 3 的幻方子矩阵。
提示:

1 <= grid.length <= 10
1 <= grid[0].length <= 10
0 <= grid[i][j] <= 15

 * 
 * @author Administrator
 *
 */
public class Pro0840 {
    //初始化参数
    public static  int s = 0;
    private static int avg = 15;
    static {
        for(int i = 1; i<10; i++) {
            s ^= i;
        }
    }
    public int numMagicSquaresInside(int[][] grid) {
        if(grid == null || grid.length < 3 || grid[0].length < 3) return 0;
        int rows = grid.length, cols = grid[0].length;
        int ans = 0;
        for(int r = 0; r < rows - 2; r++) {
            for(int c = 0; c < cols - 2; c++) {
                //r r+1 r+2
                //c c+1 c+2
                if(isOne2Night(grid, r, c) && isRowEqual(grid, r, c) && isColEqual(grid, r, c) && isDiagonalEqual(grid, r,c )) {
                    ++ans;
                }
            }
        }
        return ans;
    }
    private boolean isRowEqual(int[][] grid, int r, int c) {
        int sum = 0;
        for(int i = r;i < r + 3; i++) {
            for(int j = c;j < c+3; j++) {
                sum +=grid[i][j];
            }
            if(sum != avg) return false;
            sum = 0;
        }
        return true;
    }
    private boolean isColEqual(int[][] grid, int r, int c) {
        int sum = 0;
        for(int i = c;i < c + 3; i++) {
            for(int j = r;j < r+3; j++) {
                sum +=grid[j][i];
            }
            if(sum != avg) return false;
            sum = 0;
        }
        return true;
    }
    //对角线
    private boolean isDiagonalEqual(int[][] grid, int r, int c) {
        return grid[r][c] + grid[r+1][c+1] + grid[r+2][c+2] == grid[r+2][c] + grid[r+1][c+1] + grid[r][c+2];
    }
    private boolean isOne2Night(int[][] grid, int r, int c) {
        int ors = s;
        for(int i = r;i < r + 3; i++) {
            for(int j = c;j < c+3; j++) {
                ors ^= grid[i][j];
            }
        }
        return ors == 0;
    }
}
